package com.aplink.generic.xmlparser;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.aplink.generic.constant.ConfigParameter;
import com.aplink.generic.constant.ObjProConstant;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.pojo.TableInfo;

public class TableInfoParser {
    private static String getTextNodeValue(final Node node) {
        Node child;
        if (node != null) {
            if (node.hasChildNodes()) {
                child = node.getFirstChild();
                while (child != null) {
                    if (child.getNodeType() == Node.TEXT_NODE) {
                        return child.getNodeValue();
                    }
                    child = child.getNextSibling();
                }
            }
        }
        return "";
    }

    public static ArrayList<TableInfo> parse(final Document doc) {
        final ArrayList<TableInfo> tableInfoList = new ArrayList<TableInfo>();
        final NodeList nList = doc
                .getElementsByTagName(ConfigParameter.TABLE_STRUCTURE);
        for (int temp = 0; temp < nList.getLength(); temp++) {
            final TableInfo tableInfo = new TableInfo();
            final StringBuilder createTableQuery = new StringBuilder();
            final Node nNode = nList.item(temp);
            String tableId = "";
            // set tableInfo ID
            if (nNode.hasAttributes()) {
                final Attr attr = (Attr) nNode.getAttributes().getNamedItem(
                        ConfigParameter.TABLE_ID);
                if (attr != null) {
                    tableId = attr.getNodeValue();
                    tableInfo.setTableName(tableId);
                    createTableQuery.append("CREATE TABLE " + tableId + " ( ");
                }
            }
            // set obj_prop tags
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                final Element element = (Element) nNode;
                // get Obj_prop tags of this node
                final NodeList ObjPropNodes = element
                        .getElementsByTagName(ConfigParameter.TABLE_OBJ_PROP);
                for (int objIndex = 0; objIndex < ObjPropNodes.getLength(); objIndex++) {
                    final Node nObjPropNode = ObjPropNodes.item(objIndex);
                    final ObjPropInfo objPropInfo = new ObjPropInfo();
                    if (nObjPropNode.getNodeType() == Node.ELEMENT_NODE) {

                        final Element elementObjPropNode = (Element) nObjPropNode;
                        if (elementObjPropNode.hasAttributes()) {
                            final String defaultValue = XMLPaserUtil
                                    .getAttrValue(nObjPropNode,
                                            ObjProConstant.OBJ_DEFAULT_VALUE);
                            if (defaultValue != null) {
                                objPropInfo.setDefaultValue(defaultValue);
                            }
                        }
                        String content = "";
                        String objClass = "";
                        // get ID of this property
                        NodeList nodes = elementObjPropNode
                                .getElementsByTagName(ObjProConstant.OBJ_CLASS_ID);
                        if (nodes.getLength() != 0) {
                            content = TableInfoParser.getTextNodeValue(nodes
                                    .item(0));
                            objPropInfo.setTableName(content); // done
                            objClass = content;
                        }

                        // get ID of this property
                        nodes = elementObjPropNode
                                .getElementsByTagName(ObjProConstant.OBJ_PROP_ID);
                        if (nodes.getLength() != 0) {
                            content = TableInfoParser.getTextNodeValue(nodes
                                    .item(0));
                            objPropInfo.setColumnName(content); // done
                        }

                        // check isKey
                        final Node nNodeID = nodes.item(0);
                        final Element elementchild = (Element) nNodeID;
                        final String iskey = elementchild
                                .getAttribute(ObjProConstant.OBJ_PROP_ISKEY);
                        if (iskey.compareToIgnoreCase("Y") == 0) {
                            objPropInfo.setKey(true); // done
                        }

                        // check isAuto
                        final String isAuto = elementchild
                                .getAttribute(ObjProConstant.OBJ_PROP_ISAUTO);
                        if (isAuto.compareToIgnoreCase("Y") == 0) {
                            objPropInfo.setIsAuto(true); // done
                        }

                        // get datatype of this property
                        nodes = elementObjPropNode
                                .getElementsByTagName(ObjProConstant.OBJ_PROP_DATATYPE);
                        if (nodes.getLength() != 0) {
                            content = TableInfoParser.getTextNodeValue(nodes
                                    .item(0));
                            objPropInfo.setDataType(content); // done
                        }

                        // we add this objPropInfo into objPropInfoList
                        if (objClass.equalsIgnoreCase(tableId)) {
                            createTableQuery.append(objPropInfo.getColumnName()
                                    + " ");
                            createTableQuery.append(objPropInfo.getDataType()
                                    .getValue());
                            if (objPropInfo.isKey()) {
                                createTableQuery.append(" PRIMARY KEY ");
                                if (objPropInfo.isAuto() == true) {
                                    createTableQuery.append(" AUTOINCREMENT ");
                                }
                            } else {
                                if (objPropInfo.getDefaultValue() != null) {
                                    createTableQuery.append(" DEFAULT "
                                            + objPropInfo.getDefaultValue());
                                }
                            }
                            if (objIndex < (ObjPropNodes.getLength() - 1)) {
                                createTableQuery.append(" , ");
                            }
                            tableInfo.addColumList(objPropInfo);
                        }
                    }

                }
            }
            // add this tableInfo into tableInfoList
            createTableQuery.append(" );");
            tableInfo.setCreateTableQuery(createTableQuery.toString());
            tableInfoList.add(tableInfo);
        }
        return tableInfoList;
    }

    public static ArrayList<TableInfo> parserTableStructure(final int xmlFileId) {
        try {
            final Document document = XMLPaserUtil.openDocumentFrom(xmlFileId);
            return TableInfoParser.parse(document);
        } catch (final ParserConfigurationException e) {
            e.printStackTrace();
        } catch (final SAXException e) {
            e.printStackTrace();
        } catch (final IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
